Zeelam's Blog.

Spring Cloud的正确使用姿势2 - Spring Boot

字数统计: 2,526阅读时长: 10 min
2019/04/30 Share

Spring Boot是什么

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.

还是直接从Spring官方摘下来,Spring Boot实际上就是方便你快速构建Spring Applications的工具。重点在最后you can “just run”,Spring Boot真的可以帮助你直接Run去启动一个Spring应用。

just run

上面了说这么多,到底什么是you can “just run”呢?

这个首先就要对比一下传统模式下我们搭建一个Spring based Application的时候需要怎么做:

  • 引入Spring相关的jar包
    • 使用Maven或者Gradle这样的管理工具
    • 没有管理工具,则要手动的去把jar包复制到项目的classpath目录下
  • 编写ApplicationContext.xml文件
    • 引入一些配置文件,比如说db.properties等
    • 在XML中编写我们需要Spring容器帮我们管理的bean
  • 启动Spring容器

以上只是一个粗略的过程,而在实际开发中,这些工作显得十分繁琐,举个栗子:

首先需要管理好jar包,防止引用多了或者少了,多了会出现jar包冲突,少了则程序跑不起来。

其次,我们要管理很多的properties文件和XML文件,尤其是applicationContext.xml,有时候我们会将applicationContext.xml分成多份进行编写,比如说在Web项目下,我们可能将SpringMVC相关的配置项单独写在一个XML中,然后再通过import标签将他们组合起来。在这之中,我们往往可能造成如下的问题,bean写重复了,忘记写一些bean了或者是bean中的包名、类名写错了。这些问题都可能造成我们的项目跑不起来。

最后,我们启动Spring容器的时候也可能写错,比如说我们使用ClassPathXmlApplicationContext这个类来启动,然后XML的名字填错了呢?

以上都只是可能遇到的一部分坑而已。同时,对比其他语言,比如说Python,PHP,直接

1
pip install django

或者有WAMP或者LAMP环境下载即用,可能其他开发者已经在开发内容的时候,我们还在配置环境,这实在不够优雅。但是Spring Boot的出现帮助我们解决了这些个问题。

Spring Boot如何帮我们解决这些问题

约定优于配置

这些都得益于这样的理念:

约定优于配置

通俗的来说,就是Spring太强大,太自由了,你可以随便怎么玩,比如说我喜欢我的XML文件就叫java666.xml,那我只要在new ClassPathXmlApplicationContext类时,把class path:java666.xml当作参数传进去就可以了。

There are a thousand Hamlets in a thousand people’s eyes.

一千个人眼中有一千个哈姆雷特 (用英文就是为了装一下13 逃

每个人都有不同的命名方式或者配置,但是程序猿的工作确是一个相互协作的过程,当你看到其他人的代码时,甚至是自己以前写的代码时,是不是都会觉得,我勒个去,这是个啥?所以就出现了约定,都叫做applicationContext.xml吧,这样大家都懂。

基于约定、Spring JavaConfig和Maven。Spring Boot完美的帮我们解决了之前配置繁琐的问题。

Spring JavaConfig

什么?Spring JavaConfig又是什么。通俗的讲JavaConfig是Spring提供的一系列Annotation(注解),利用这一些Annotation,可以帮助我们将XML中的配置迁移到代码中,这样就能减少项目中对XML的使用。

这些Annotation包括

  • @Configuration
  • @Bean
  • @ComponentScan
  • @Import
  • @PropertySource、@PropertySources
  • @Profile、@ActiveProfile

由于我们的侧重点是Spring Cloud,所以这里就简单介绍下。比如说被@Configuration标注的类就是我们的配置类,可以当作是替代我们的applicationContext.xml。而在配置类中,我们使用@Bean注解来配置需要被Spring容器管理的bean。@ComponentScan则是表示Spring所需要扫描的包。

这样说太抽象了,直接上代码,更加清晰:

1
2
3
4
5
6
7
8
9
10
@Configuration
@ComponentScan("com.zeelam.spring_boot")
public class Config {

@Bean
public MyBean myBean(){
return new MyBean();
}

}

以上代码中Config类以Java代码的方式替代了applicationContext.xml中的最重要的作用,配置bean,所以相当于代替了applicationContext.xml

@ComponentScan则相当于替代了applicationContext.xml中的标签

@Bean则是替代了标签

以上的方式都是使用Java代码的方式实现了在XML中所需要完成的工作,所以取名叫JavaConfig。那么重点来了:

有了JavaConfig和约定,我们则可以顺利的把很多东西按照约定搬到Java代码中去,不用再费劲去写XML了

Maven

Maven我相信大家再熟悉不过了,通过Maven我们可以方便的构建我们的项目、管理jar包、甚至是利用Maven的Plugin帮助我们编译、打包我们的项目。而Spring Boot则是借助了Maven对于项目的管理帮助我们解决了各种jar包依赖的问题。

通过将pom文件的parent配置为Spring-Boot-Starters-parent这个pom文件,以及引用Spring-Boot-Starters的其他各个pom文件,这样就配置好了我们使用Spring开发环境或需要依赖的jar包以及版本。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
 <modelVersion>4.0.0</modelVersion>

<!-- spring-boot-starter-parent -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.4.RELEASE</version>
<relativePath/>
</parent>

<groupId>com.zeelam.learning</groupId>
<artifactId>spring_boot</artifactId>
<version>1.0.0</version>
<name>spring_boot</name>
<description>Demo project for Spring Boot</description>

<properties>
<java.version>1.8</java.version>
</properties>

<!-- 引入其他spring-boot-starter的pom文件 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<!-- spring-boot提供的maven插件 -->
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>

以上为使用Spirng Boot Initializr生成的Spring Boot项目的pom文件。

其中可以发现标签中有一个spring-boot-starter-parent,实际上他内部还有一个父级的pom文件spring-boot-dependencies,而这个文件中,有两个重要的标签

熟悉Maven的朋友可能就明白了,实际上是用来帮助我们定义各个依赖jar包的版本,而则是帮助我们在子pom文件中统一管理依赖jar包(注意:这里并没有真正的把jar包导入到项目中

当我们在自己的pom文件中,在标签中引入其他依赖时(这个时候才真正的引入了jar),就不用写版本号了。

那么spring-boot-starter又是什么呢,官方解释是

Core starter, including auto-configuration support, logging and YAML

点进去看一下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
<version>2.1.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
<version>2.1.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.1.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>5.1.6.RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.23</version>
<scope>runtime</scope>
</dependency>

其实还是在帮我们引入jar包嘛。spring-boot就包含了我们之前手动配置Spring环境的时候需要引入的一系列jar包。然后就是Spring Boot中所需的spring-boot-autoconfigure,logging等一些依赖了。

有些朋友估计又有疑问了,spring-boot-autoconfigure又是什么,实际上就是利用Java Config,使得我们约定好的一些配置Bean,比方说我们配置MySQL的时候,肯定需要配置Datasource这个bean,而Datasouces这个bean中当然有url、driverClassName、username、password等属性要配置(可以是默认的也可以是手动在application.properties中配置的)可以自动交给Spring容器管理。(至于怎么做到自动的,这个后面会有专门的Spring Boot系列文章来剖析,不然的话Spring Cloud写不完了…逃)

总结

至此,基于约定优于配置、Java Config、Maven(Gradle),Spring Boot帮助我们解决了如下几个传统方式下构建Spring Application时的问题:

  • XML文件过多难以管理以及XML中没有编译器提示造成的写错后难查找的问题
  • jar包管理、冲突和版本问题
  • 启动、部署简单(一个main方法解决问题)

使用Spring Boot

以上讲了那么多Spring Boot是什么,有什么优点,基于什么实现的。终于到了使用Spring Boot的环节。其实使用Spring Boot非常简单,有以下几种方法:

手动创建Maven项目

  • 引用Spring Boot提供的jar包
  • 在项目的包名下创建一个Application类
  • 打上@SpringBootApplication注解
  • 在main方法上,写一句 SpringApplication.run(Application.class, args); 即可
1
2
3
4
5
6
7
8
9
10
11
12
13
package com.zeelam.learning.spring_boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}

}

注意:项目包名的意思是com.zeelam.learning.spring_boot下面,也就是说在这个包下面,还有其他很多的包,比如说com.zeelam.learning.spring_boot.domain,com.zeelam.learning.spring_boot.mapper等等。

之所以需要这样做的原因是@SpringBootApplication注解实际上是由三个注解:

  • @SpringBootConfiguration

  • @EnableAutoConfiguration

  • @ComponentScan

组成,而在ComponentScan上默认的的值是扫描当前包及其子包,所以一般都将Application这个类放在最上层的包里面。

https://start.spring.io/上面构建并下载下来

在IDE中使用提供的插件直接构建

实际上还是通过Spring Initializr来做这件事,只是IDE帮你直接封装好了,不需要再去下载到本地再打开。这里使用IDEA作为演示

然后按下Next,IDEA就会直接帮你构建一个Spring Boot项目,是不是So easy。

目录
  1. 1. Spring Boot是什么
  2. 2. just run
  3. 3. Spring Boot如何帮我们解决这些问题
    1. 3.1. 约定优于配置
    2. 3.2. Spring JavaConfig
    3. 3.3. Maven
    4. 3.4. 总结
  4. 4. 使用Spring Boot
    1. 4.1. 手动创建Maven项目
    2. 4.2. 从https://start.spring.io/上面构建并下载下来
    3. 4.3. 在IDE中使用提供的插件直接构建